/**
 * Created by gzj on 16/10/12.
 */


class Game {
    /**
     * @param canvas {HTMLCanvasElement} 画板
     */
    constructor(canvas) {
        this.width = 800;
        this.height = 500;
        this.scaleRatio = 100; // 缩放系数

        this.myWorld = new MyWorld(this.width / this.scaleRatio, this.height / this.scaleRatio);
        this.phyWorld = new PhyWorld(this.width / this.scaleRatio, this.height / this.scaleRatio);

        this.world = this.myWorld;
        // this.world = this.phyWorld;
        this.drawer = new GraphicEngine(canvas, this.width, this.height);

        this._showX = document.querySelector('#x');
        this._showY = document.querySelector('#y');
        this._showWidth = document.querySelector('#width');
        this._showHeight = document.querySelector('#height');
        this._showVX = document.querySelector('#vx');
        this._showVY = document.querySelector('#vy');

        this.lastObjId = null;
    }

    set showX(val) {this._showX.innerHTML = val.toFixed(3)}
    set showY(val) {this._showY.innerHTML = val.toFixed(3)}
    set showWidth(val) {this._showWidth.innerHTML = val.toFixed(3)}
    set showHeight(val) {this._showHeight.innerHTML = val.toFixed(3)}
    set showVX(val) {this._showVX.innerHTML = val.toFixed(3)}
    set showVY(val) {this._showVY.innerHTML = val.toFixed(3)}

    /**
     * @param x {number} 游戏世界横坐标
     * @param y {number} 游戏世界纵坐标
     * @return {object} 画布坐标
     */
    toCanvasPos(x, y) {
        return {
            x: x * this.scaleRatio,
            y: this.height - y * this.scaleRatio
        }
    }

    /**
     * @param x {number} 画布横坐标
     * @param y {number} 画布纵坐标
     * @return {object} 游戏世界坐标
     */
    toGamePos(x, y) {
        return {
            x: x / this.scaleRatio,
            y: (this.height - y) / this.scaleRatio
        }
    }

    /**
     * 注册交互事件
     */
    regEvents() {
        const thiz = this;
        const canvas = this.drawer.canvas;
        const canvasPos = getPosition(canvas);

        canvas.onclick = function(e) {
            const cx = e.clientX - canvasPos.x;
            const cy = e.clientY - canvasPos.y;

            const gameXY = thiz.toGamePos(cx, cy);
            console.warn('canvas:', {x:cx, y:cy}, 'game:', gameXY);

            const rvx = (Math.random() - 0.5) * 2 * 5;
            thiz.lastObjId = thiz.world.addObj(new PhyObj(gameXY.x, gameXY.y, 30, 30, rvx, 0, 2));
        };
    }

    /**
     * 渲染
     */
    render() {
        this.drawer.clearAll();

        for(let id in this.world.objs) {
            if(this.world.objs.hasOwnProperty(id)) {
                let obj = this.world.objs[id];
                let cXY = this.toCanvasPos(obj.x, obj.y);

                this.drawer.drawCircle(cXY.x - obj.width / 2, cXY.y - obj.height / 2, obj.height / 2, obj.color.style);
            }
        }
    }

    /**
     * 游戏主循环
     */
    mainLoop() {
        const thiz = this;

        // 物理引擎工作
        this.world.calculate();
        // 图形引擎工作
        this.render();
        // 其他逻辑工作
        this.customeLogic();

        // 进入下一个循环
        requestAnimationFrame(() => {thiz.mainLoop()});
    }

    /**
     * 开始游戏
     */
    start() {
        // 相关初始化工作
        this.regEvents();

        this.mainLoop();
    }

    /**
     * 其他逻辑
     */
    customeLogic() {
        const obj = this.world.getObj(this.lastObjId);
        if(obj) {
            this.showX = obj.x;
            this.showY = obj.y;
            this.showWidth = obj.width;
            this.showHeight = obj.height;
            this.showVX = obj.vx;
            this.showVY = obj.vy;
        }
    }

    switchWorld() {

    }
}
